package state

/**
表相关指令
*/

const LFIELDS_PER_FLUSH = 50

func newTable(i Instruction, vm LuaVM) {
	a, b, c := i.ABC()
	a += 1
	vm.CreateTable(Fb2int(b), Fb2int(c))
	vm.Replace(a)
}
func getTable(i Instruction, vm LuaVM) {
	a, b, c := i.ABC()
	a += 1
	b += 1
	vm.GetRK(c)
	vm.GetTable(b)
	vm.Replace(a)
}

func setTable(i Instruction, vm LuaVM) {
	a, b, c := i.ABC()
	vm.GetRK(b)
	vm.GetRK(c)
	vm.SetTable(a + 1)
}

/**
todo-xxd setList 的 a 只能是 50的倍数吗
*/
func setList(i Instruction, vm LuaVM) {
	a, b, c := i.ABC()
	a += 1
	if c > 0 {
		c = c - 1
	} else {
		c = Instruction(vm.Fetch()).Ax()
	}
	idx := int64(c * LFIELDS_PER_FLUSH)
	if b == 0 {
		b = int(vm.ToInteger(-1)) - a - 1
		vm.Pop(1)
	}
	for i := 1; i <= b; i++ {
		idx++
		vm.PushValue(a + i)
		vm.SetI(a, idx)
	}

	if b == 0 {
		for i := vm.RegisterCount() + 1; i <= vm.GetTop(); i++ {
			idx++
			vm.PushValue(i)
			vm.SetI(a, idx)
		}
		vm.SetTop(vm.RegisterCount())
	}
}

func Int2fb(x int) int {
	e := 0
	if x < 8 {
		return x
	}
	for x >= (8 << 4) {
		x = (x + 0xf) >> 4 /* x =ceil (x/16) */
		e += 4
	}
	for x >= (8 << 1) {
		x = (x + 1) >> 1 //x==ceil(x/2)
		e++
	}
	return ((e + 1) << 3) | (x - 8)
}

func Fb2int(x int) int {
	if x < 8 {
		return x
	} else {
		return ((x & 7) + 8) << uint((x>>3)-1)
	}
}
